/*
 * @Author: shijianxin
 * @Date: 2022-04-22 16:37:47
 * @Description: 电影状态
 */

import { Reducer } from "react";
import { ISearchCondition } from "../../services/CommonType";
import { IMovie } from "../../services/MovieService";
import {
  MovieActions,
  MovieChangeSwitchAction,
  SaveMoviesAction,
  SetConditionAction,
  SetDeleteAction,
  SetLoadingAction,
} from "../actions/MovieAction";

export type IMovieCondition = Required<ISearchCondition>;

export interface IMovieState {
  /**
   * 电影数组
   */
  data: IMovie[];
  /**
   * 查询条件
   */
  condition: IMovieCondition;
  /**
   * 总记录数
   */
  total: number;
  /**
   * 是否正在加载数据
   */
  isLoading: boolean;
}

const defaultState: IMovieState = {
  data: [],
  condition: {
    page: 1,
    limit: 10,
    key: "",
  },
  total: 0,
  isLoading: false,
};

type MovieReducer<A> = Reducer<IMovieState, A>;

const saveMovie: MovieReducer<SaveMoviesAction> = function (state, action) {
  return Object.assign({}, state, {
    ...state,
    data: action.payload.movies,
    total: action.payload.total,
  });
};

const setCondition: MovieReducer<SetConditionAction> = function (
  state,
  action
) {
  return Object.assign({}, state, {
    ...state,
    condition: {
      ...state.condition,
      ...action.payload,
    },
  });
};

const setLoading: MovieReducer<SetLoadingAction> = function (state, action) {
  return {
    ...state,
    isLoading: action.payload,
  };
};

const deleteMovie: MovieReducer<SetDeleteAction> = function (state, action) {
  return {
    ...state,
    data: state.data.filter((m) => m._id !== action.payload),
    total: state.total - 1,
  };
};

const changeSwitch: MovieReducer<MovieChangeSwitchAction> = function (
  state,
  action
) {
  const movie = state.data.find((d) => d._id === action.payload.id);
  if (!movie) {
    return state;
  }
  const newMovie = { ...movie };
  newMovie[action.payload.type] = action.payload.newVal;
  const newData = state.data.map((d) => {
    if (d._id === action.payload.id) {
      return newMovie;
    }
    return d;
  });
  return {
    ...state,
    data: newData,
  };
};

export default function (
  state: IMovieState = defaultState,
  action: MovieActions
) {
  switch (action.type) {
    case "movie_delete":
      return deleteMovie(state, action);
    case "movie_save":
      return saveMovie(state, action);
    case "movie_setCondition":
      return setCondition(state, action);
    case "movie_switch":
      return changeSwitch(state, action);
    default:
      return setLoading(state, action);
  }
}
